<?php
/**
 * ResultSet class, building sql query to the search tunes in the database
 */
class ResultSet
{
  private $clauses; // array of conditions
  private $sortBy;
  private $order;
  private $limit;
  private $offset;
  private $operator;
  private $diacritics;//boolean
  
  public function __construct()
  {
    $this->clauses    = array();
    $this->limit      = 20;
    $this->offset     = 0;
    $this->sortBy     = 'stamp';
    $this->order      = 'DESC';
    $this->operator   = 'OR';
    $this->diacritics = false;
  }
  
  /**
   *Adds clause to the sql query
   *
   *@param string $field database field name
   *@param string $operator comparison operator ("like", "=", etc)
   *@param string $value value to search
   */
  public function addClause($field,$operator,$value)
  {
    $this->clauses[] = $field.' '.$operator.' "'.$value.'"';
  }

  /**
   *Simple search using keyword on artist, album, title and genre
   *
   *@param strin $keyword
   */
  public function simple($keyword)
  {
    $this->clauses = array();
    $this->offset = 0;
    $this->operator= 'OR';
    $keyword = trim($keyword);
    if(!empty($keyword))
    {
      if(!$this->diacritics)
      {

        $keyword = noDiacritics(utf8_decode($keyword),false);

				$this->addClause('noDiacritics(artist)','like','%'.$keyword.'%');
        $this->addClause('noDiacritics(title)','like','%'.$keyword.'%');
        $this->addClause('noDiacritics(album)','like','%'.$keyword.'%');
        $this->addClause('genre','like','%'.htmlentities(utf8_decode($keyword),ENT_QUOTES).'%');

      }
      else
      {
        $keyword = htmlentities(utf8_decode($keyword),ENT_QUOTES);

        $this->addClause('artist','like','%'.$keyword.'%');
        $this->addClause('title','like','%'.$keyword.'%');
        $this->addClause('album','like','%'.$keyword.'%');
        $this->addClause('genre','like','%'.$keyword.'%');
      }
    }
  }

  /**
   *Query ORDER BY
   *
   *@param string $sortBy database fields seperated by commas
   *@param string $order sorting order ("ASC" or "DESC")
   */
  public function order($sortBy,$order)
  {
    $this->sortBy = $sortBy;
    $this->order  = $order;
  }
  
  /**
   *Sort column (will alternate ASC and DESC)
   *
   *@param string $column Name of the column
   */
  public function sortColumn($column)
  {
    if($this->order == 'ASC')
    {
      $this->order = 'DESC';
    }
    else
    {
      $this->order = 'ASC';
    }
    //$this->sortBy = 'low_case('.$column.')';
    $this->sortBy = $column;
  }
  
  /**
   *Set search offset
   *
   *@param integer $offset
   */
  public function setOffset($offset)
  {
    $this->offset = $offset;
  }
  
  /**
   *Execute search and returns array with count and results
   *
   *@return array
   */
  private function doSearch()
  {
    $sql_result_set = "SELECT * FROM song";
    $sql_count = "SELECT count(*) FROM song";
    if(count($this->clauses)>0)
    {
      $sql_result_set.= " WHERE ".implode(" ".$this->operator." ",$this->clauses);
      $sql_count.= " WHERE ".implode(" ".$this->operator." ",$this->clauses);
    }
    $sql_result_set.=" ORDER BY ".$this->sortBy." ".$this->order." LIMIT ".$this->offset.",".$this->limit;// result set gets extra treatment
    $dbh = new dbSql();
    $dbh->registerFn('noDiacritics','noDiacritics');
    $dbh->registerFn('low_case','mb_strtolower');
    $dbh->registerFn('soundex','soundex');
    $result_set = $dbh->query($sql_result_set);
    $count = $dbh->query($sql_count);
    $res = array('count'=>$count[0]['count(*)'],'results'=>$result_set);

    return $res;
  }
  
  /**
   *Execute search and then output datagrid and pager html
   *
   *@return string $html
   */
  public function mkHtml()
  {
    $res = $this->doSearch();
    if($res['count'] > $this->limit)
    {
      if($this->offset > 0)
      {
        $offset_value = $this->offset - $this->limit;
        $prev_button = '<input onmouseover="help(str.hlp_previous_page);" onclick="setOffset('.$offset_value.');return false;" type="image" src="app/skin/transparent.gif" class="btnResPrevious"/>&nbsp;';
      }
      else
      {
        $prev_button = '';
      }

      $pager='<div class="pager">'.$prev_button.'<select id="pager" title="'.STR_UI_PAGES.'" onmouseover="help(str.ui_page);" onchange="setOffset(this.value);">';

      for($i=0,$j=1;$i<$res['count'];$i=$i+$this->limit,$j++)
      {
        if($i==$this->offset)
        {
          $pager.=EOL.'<option selected="selected" value="'.$i.'">'.$j.'</option>';
        }
        else
        {
          $pager.=EOL.'<option value="'.$i.'">'.$j.'</option>';
        }
      }

      $pager.='</select>';
      
      if($this->offset < $i-$this->limit)
      {
        $offset_value = $this->offset + $this->limit;
        $pager.= '&nbsp;<input onmouseover="help(str.hlp_next_page);" onclick="setOffset('.$offset_value.');return false;" type="image" src="app/skin/transparent.gif" class="btnResNext"/></div>';
      }
      else
      {
        $pager.= '</div>';
      }
    }
    else
    {
      $pager = '';
    }
    // datagrid
    if($res['count'] == 0)
    {
      $html = STR_ERR_NO_RESULTS;
    }
    else
    {
      if($this->order == 'DESC')
      {
        $sortClass = 'sortDown';
      }
      else
      {
        $sortClass = 'sortUp';
      }
      $sArtist  = '';
      $sTitle   = '';
      $sAlbum   = '';
      $sGenre   = '';
      $sStamp   = '';
      switch($this->sortBy)
      {
      /*
        case 'low_case(artist)':
          $sArtist = ' class="'.$sortClass.'"';
          break;
        case 'low_case(title)':
          $sTitle = ' class="'.$sortClass.'"';
          break;
        case 'low_case(album)':
          $sAlbum = ' class="'.$sortClass.'"';
          break;
        case 'low_case(genre)':
          $sGenre = ' class="'.$sortClass.'"';
          break;
        case 'low_case(stamp)':
          $sStamp = ' class="'.$sortClass.'"';
          break;
      */
        case 'artist':
          $sArtist = ' class="'.$sortClass.'"';
          break;
        case 'title':
          $sTitle = ' class="'.$sortClass.'"';
          break;
        case 'album':
          $sAlbum = ' class="'.$sortClass.'"';
          break;
        case 'genre':
          $sGenre = ' class="'.$sortClass.'"';
          break;
        case 'stamp':
          $sStamp = ' class="'.$sortClass.'"';
          break;
      }
      $html = '<table><tr>
        <th onclick="sortBy(\'artist\');return false;" onmouseover="help(str.hlp_sort);"'.$sArtist.'>'.STR_UI_ARTIST.'</th>
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th><input onmouseover="help(str.hlp_check);" onclick="checkAll();return false;" type="image" src="app/skin/transparent.gif" class="btnCheck"/></th>';
        if($_SESSION['MczSession']->can('download'))
        {
          $html.='<th>&nbsp;</th>';
        }
        $html.='<th onclick="sortBy(\'title\');return false" onmouseover="help(str.hlp_sort);"'.$sTitle.'>'.STR_UI_TITLE.'</th>
        <th onclick="sortBy(\'album\');return false;" onmouseover="help(str.hlp_sort);"'.$sAlbum.'>'.STR_UI_ALBUM.'</th>
        <th onclick="sortBy(\'genre\');return false;" onmouseover="help(str.hlp_sort);"'.$sGenre.'>'.STR_UI_GENRE.'</th>
        <th onclick="sortBy(\'stamp\');return false;" onmouseover="help(str.hlp_sort);"'.$sStamp.'>'.STR_UI_STAMP.'</th>
        </tr>';
      $i = 0;
      $trStyle = '';
      foreach($res['results'] as $result)
      {
        $genre = trim($result['genre']);
        if(empty($genre))
        {
          $result['genre'] = 'Unknown';
        }
        $album = trim($result['album']);
        if(empty($album))
        {
          $result['album'] = "Unknown";
        }
        if($i%2){$trStyle = 'tr1';}else{$trStyle = 'tr2';}
        $html.= '<tr class="'.$trStyle.'">
                  <td class="tdArtist"><div class="edit_inline" onmouseover="help(str.hlp_edit_tag);mkTagEditable(this,\''.$result['id'].'\',\'artist\');">'.utf8_encode(ucfirst(html_entity_decode($result['artist'],ENT_QUOTES))).'</div></td>
                  <td class="tdTag"><input type="image" src="app/skin/transparent.gif" class="btnEdit" onmouseover="help(str.hlp_tag_form);" onclick="tagsForm(\''.$result['id'].'\');return false;"/></td>
                  <td class="tdAdd" onmouseover="help(str.hlp_add_to_cue);"><input type="image" src="app/skin/transparent.gif" class="btnAddToCue" onmouseover="help(str.hlp_add_to_cue);" onclick="addToCue(\'mczid\',\'\',\''.$result['id'].'\');return false;" /></td>
                  <td class="tdCheck" onmouseover="help(\' \');"><input type="checkbox" class="checker" id="'.$result['id'].'"/></td>';
        if($_SESSION['MczSession']->can('download'))
        {
          $html.='<td class="tdDownload"><a href="?c=dl&amp;songId='.$result['id'].'"><img src="app/skin/transparent.gif" class="btnDownload" alt="download" onmouseover="help(str.hlp_download);"/></a></td>';
        }
                  
          $html.='<td class="tdTitle"><div onmouseover="help(str.hlp_edit_tag);mkTagEditable(this,\''.$result['id'].'\',\'title\');">'.utf8_encode(ucfirst(html_entity_decode($result['title'],ENT_QUOTES))).'</div></td>
                  <td class="tdAlbum"><div onmouseover="help(str.hlp_edit_tag);mkTagEditable(this,\''.$result['id'].'\',\'album\');">'.utf8_encode(ucfirst(html_entity_decode($result['album'],ENT_QUOTES))).'</div></td>
                  <td class="tdGenre"><div onmouseover="help(str.hlp_edit_tag);mkTagEditable(this,\''.$result['id'].'\',\'genre\');">'.utf8_encode(ucfirst(html_entity_decode($result['genre'],ENT_QUOTES))).'</div></td>
                  <td class="tdStamp"><div onmouseover="help($(this).html());">'.date("y-m-d",$result['stamp']).'</div></td>
                </tr>';
        $i++;
      }
      $html.= '<tr>
      <td class="tdFoot">'.$pager.'</td>
      <td colspan="8" class="tdFoot"><form action="#" method="post" onsubmit="checkAction();return false;">
        <label>'.STR_UI_FOR_SELECTED.'</label>
        <select name="selectedAction" id="selectedAction" onchange="taggerSwitch();" onmouseover="help(str.hlp_checkers_action);">
          <option value="addToCue">'.STR_UI_ENQUEUE.'</option>
          <option value="addToPls">'.STR_UI_ADD_TO_PLS.'</option>';
          if($_SESSION['MczSession']->can('mod_own') or $_SESSION['MczSession']->can('mod_all'))
          {
            $html.='<option value="tag">'.STR_UI_CHANGE_TAG.'</option>';
          }
          if($_SESSION['MczSession']->can('del_own') or $_SESSION['MczSession']->can('del_all'))
          {
            $html.='<option value="delete">'.STR_UI_DELETE.'</option>';
          }
        $html.='</select>
        <span id="playlistSelect" style="display:none;">toto</span>
        <span id="tagger" style="display:none;">
          <select name="tagField" id="tagField" onmouseover="help(str.hlp_tag);">
            <option value="artist">'.STR_UI_ARTIST.'</option>
            <option value="title">'.STR_UI_TITLE.'</option>
            <option value="album">'.STR_UI_ALBUM.'</option>
            <option value="genre">'.STR_UI_GENRE.'</option>
          </select>
          <label>'.STR_UI_TO.'</label>
          <input type="text" id="tagValue" onmouseover="help(str.hlp_tag_value);"/>
        </span>
        <input type="submit" value="'.STR_UI_OK.'"/>
      </form></td>
      </tr></table>';
    }
    return $html;
  }
}
?>
